package com.emapp.lccode.base

import android.graphics.Bitmap
import android.text.TextUtils
import android.util.Log
import cat.ereza.customactivityoncrash.config.CaocConfig
import com.emapp.lccode.BuildConfig
import com.emapp.lccode.activity.ErrorActivity
import com.emapp.lccode.activity.LogoKtActivity
import com.emapp.lccode.bean.UserKt
import com.emapp.lccode.mode.AppViewModel
import com.emapp.lccode.utils.MmkvUtil
import com.emapp.lccode.utils.toJsonStr
import com.google.gson.Gson
import com.hjq.toast.Toaster
import com.hjq.toast.style.WhiteToastStyle
import com.kingja.loadsir.core.LoadSir
import com.nostra13.universalimageloader.cache.disc.impl.UnlimitedDiskCache
import com.nostra13.universalimageloader.cache.disc.naming.Md5FileNameGenerator
import com.nostra13.universalimageloader.cache.memory.impl.UsingFreqLimitedMemoryCache
import com.nostra13.universalimageloader.core.DisplayImageOptions
import com.nostra13.universalimageloader.core.ImageLoader
import com.nostra13.universalimageloader.core.ImageLoaderConfiguration
import com.nostra13.universalimageloader.core.assist.ImageScaleType
import com.nostra13.universalimageloader.core.assist.QueueProcessingType
import com.nostra13.universalimageloader.core.download.BaseImageDownloader
import com.nostra13.universalimageloader.utils.L
import com.nostra13.universalimageloader.utils.StorageUtils
import com.tencent.smtt.sdk.QbSdk
import com.tencent.smtt.sdk.QbSdk.PreInitCallback
import com.umeng.commonsdk.UMConfigure
import me.hgj.jetpackmvvm.base.BaseApp
import me.hgj.jetpackmvvm.demo.app.weight.loadCallBack.EmptyCallback
import me.hgj.jetpackmvvm.demo.app.weight.loadCallBack.ErrorCallback
import me.hgj.jetpackmvvm.demo.app.weight.loadCallBack.LoadingCallback
import me.hgj.jetpackmvvm.ext.util.jetpackMvvmLog

val appViewModel: AppViewModel by lazy { BaseApplication.appViewModelInstance }

class BaseApplication : BaseApp() {
    companion object {
        lateinit var instance: BaseApplication
        lateinit var appViewModelInstance: AppViewModel
    }
    override fun onCreate() {
        instance = this
        super.onCreate()
        Toaster.init(this, WhiteToastStyle())
        initImageLoader()
        UMConfigure.preInit(this, UmInitConfig.um_appkey, "innobank")
        MmkvUtil.init(this)
        if (MmkvUtil.getBoolean(BaseConfig.CANCEL_PRIVACY_SHOW, false)) {
            init()
        }
        appViewModelInstance = this.getAppViewModelProvider()[AppViewModel::class.java]
        LoadSir.beginBuilder()
            .addCallback(ErrorCallback()) //添加各种状态页
            .addCallback(EmptyCallback())
            .addCallback(LoadingCallback())
            .setDefaultCallback(LoadingCallback::class.java) //设置默认状态页
            .commit()
        //搜集本地tbs内核信息并上报服务器，服务器返回结果决定使用哪个内核。
        //mWebView.loadUrl("debugtbs.qq.com");//收到下载内核
        val cb: PreInitCallback = object : PreInitCallback {
            override fun onViewInitFinished(arg0: Boolean) {
                // TODO Auto-generated method stub
                //x5內核初始化完成的回调，为true表示x5内核加载成功，否则表示x5内核加载失败，会自动切换到系统内核。
                Log.e("app", " onViewInitFinished is $arg0")
            }

            override fun onCoreInitFinished() {
                // TODO Auto-generated method stub
            }
        }
        //x5内核初始化接口
        QbSdk.initX5Environment(applicationContext, cb)
        initVideo()
        //防止项目崩溃，崩溃后打开错误界面
        CaocConfig.Builder.create()
            .backgroundMode(CaocConfig.BACKGROUND_MODE_SILENT) //default: CaocConfig.BACKGROUND_MODE_SHOW_CUSTOM
            .enabled(true)//是否启用CustomActivityOnCrash崩溃拦截机制 必须启用！不然集成这个库干啥？？？
            .showErrorDetails(false) //是否必须显示包含错误详细信息的按钮 default: true
            .showRestartButton(false) //是否必须显示“重新启动应用程序”按钮或“关闭应用程序”按钮default: true
            .logErrorOnRestart(false) //是否必须重新堆栈堆栈跟踪 default: true
            .trackActivities(true) //是否必须跟踪用户访问的活动及其生命周期调用 default: false
            .minTimeBetweenCrashesMs(2000) //应用程序崩溃之间必须经过的时间 default: 3000
            .restartActivity(LogoKtActivity::class.java) // 重启的activity
            .errorActivity(ErrorActivity::class.java) //发生错误跳转的activity
            .apply()
        jetpackMvvmLog= BuildConfig.BUILD_TYPE != "release"
    }

    private fun initVideo() {
//        VideoViewManager.setConfig(
//            VideoViewConfig.newBuilder()
//                .setLogEnabled(BuildConfig.DEBUG) //调试的时候请打开日志，方便排错
//                /** 软解，支持格式较多，可通过自编译so扩展格式，结合 [xyz.doikki.dkplayer.widget.videoview.IjkVideoView] 使用更佳  */
//                .setPlayerFactory(IjkPlayerFactory.create())
//                .build()
//        )
    }

    fun init() {
        //友盟正式初始化
        val umInitConfig = UmInitConfig()
        umInitConfig.UMinit(applicationContext)
        //QQ官方sdk授权
//        Tencent.setIsPermissionGranted(true);
    }

    fun setUser(user: UserKt?) {
        if (user == null) {
            MmkvUtil.putString("user", "")
            MmkvUtil.putString("token", "")
        } else {
            MmkvUtil.putString("token", user.token)
            MmkvUtil.putString("user", user.toJsonStr())
        }
//        this.user = user
//        if (user == null) {
//            get()!!.userDao!!.delete()
//        } else {
//            get()!!.userDao!!.insertOrUpdate(user)
//        }
    }

    fun getUser(): UserKt? {
        val userStr = MmkvUtil.getString("user", "")
        return if (TextUtils.isEmpty(userStr)) {
            null
        } else {
            Gson().fromJson(userStr, UserKt::class.java)
        }
//        if (user == null) {
//            val us = get()!!.userDao!!.find()
//            if (us != null && us.size > 0) {
//                user = us[0]
//            }
//        }
//        return user
    }

    val token: String
        get() {
            return MmkvUtil.getString("token", "")
        }
    val adminId: Int
        get() {
            return getUser()?.admin_id ?: 0
        }
    /**
     * User findUser = userDao.queryBuilder().where(UserDao.Properties.Name.eq("zhangsan")).build().unique();
     * if(findUser != null){
     * userDao.deleteByKey(findUser.getId());
     * }
     */
    /**
     * 初始化imageLoader
     */
    fun initImageLoader() {
        L.writeLogs(false)
        val cacheDir = StorageUtils.getCacheDirectory(this)
        val config = ImageLoaderConfiguration.Builder(this)
            .memoryCacheExtraOptions(480, 800) // max width, max height，即保存的每个缓存文件的最大长宽
            .threadPoolSize(3) //线程池内加载的数量
            .threadPriority(Thread.NORM_PRIORITY - 2)
            .denyCacheImageMultipleSizesInMemory()
            .memoryCache(UsingFreqLimitedMemoryCache(1 * 1024 * 1024)) // You can pass your own memory cache implementation/你可以通过自己的内存缓存实现
            .memoryCacheSize(256 * 1024)
            .discCacheSize(50 * 1024 * 1024)
            .discCacheFileNameGenerator(Md5FileNameGenerator()) //将保存的时候的URI名称用MD5 加密
            .tasksProcessingOrder(QueueProcessingType.LIFO)
            .discCacheFileCount(100) //缓存的文件数量
            .discCache(UnlimitedDiskCache(cacheDir)) //自定义缓存路径
            .defaultDisplayImageOptions(DisplayImageOptions.createSimple())
            .imageDownloader(
                BaseImageDownloader(
                    this,
                    5 * 1000,
                    30 * 1000
                )
            ) // connectTimeout (5 s), readTimeout (30 s)超时时间
            .writeDebugLogs() // Remove for release app
            .build() //开始构建
        ImageLoader.getInstance().init(config)
    }

    fun getOptions(drawableId: Int): DisplayImageOptions {
        return DisplayImageOptions.Builder()
            .showImageOnLoading(drawableId)
            .showImageForEmptyUri(drawableId)
            .showImageOnFail(drawableId)
            .resetViewBeforeLoading(true)
            .cacheInMemory(true)
            .cacheOnDisc(true)
            .imageScaleType(ImageScaleType.EXACTLY)
            .bitmapConfig(Bitmap.Config.RGB_565)
            .build()
    }


}